package com.example.smartagrisys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.smartagrisys.entity.Notification;
import com.example.smartagrisys.mapper.NotificationMapper;
import com.example.smartagrisys.service.NotificationService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 消息通知服务实现类
 */
@Slf4j
@Service
public class NotificationServiceImpl extends ServiceImpl<NotificationMapper, Notification> implements NotificationService {

    @Override
    public List<Notification> getUserNotifications(Long userId) {
        LambdaQueryWrapper<Notification> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Notification::getUserId, userId)
               .eq(Notification::getDeleted, false)
               .orderByDesc(Notification::getCreateTime);
        return list(wrapper);
    }

    @Override
    public int countUnreadNotifications(Long userId) {
        LambdaQueryWrapper<Notification> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Notification::getUserId, userId)
               .eq(Notification::getIsRead, false)
               .eq(Notification::getDeleted, false);
        return Math.toIntExact(count(wrapper));
    }

    @Override
    public boolean markAsRead(Long notificationId, Long userId) {
        log.info("标记通知已读 - 通知ID: {}, 用户ID: {}", notificationId, userId);
        
        // 首先查询通知是否存在
        LambdaQueryWrapper<Notification> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Notification::getId, notificationId)
                   .eq(Notification::getUserId, userId)
                   .eq(Notification::getDeleted, false);
        
        Notification notification = getOne(queryWrapper);
        if (notification == null) {
            log.warn("标记通知已读失败 - 通知不存在或不属于该用户");
            return false;
        }
        
        // 如果通知已经是已读状态，则直接返回成功
        if (Boolean.TRUE.equals(notification.getIsRead())) {
            log.info("通知已经是已读状态，不需要再次标记");
            return true;
        }
        
        // 执行更新操作
        LambdaUpdateWrapper<Notification> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Notification::getId, notificationId)
                   .eq(Notification::getUserId, userId)
                   .eq(Notification::getDeleted, false)
                   .set(Notification::getIsRead, true)
                   .set(Notification::getReadTime, LocalDateTime.now());
        
        boolean result = update(updateWrapper);
        log.info("标记通知已读 - 结果: {}", result ? "成功" : "失败");
        
        // 尝试再次查询，确认更新是否生效
        if (result) {
            Notification updated = getById(notificationId);
            if (updated != null) {
                log.info("标记已读后通知状态: ID={}, isRead={}, readTime={}", 
                       updated.getId(), updated.getIsRead(), updated.getReadTime());
            }
        }
        
        return result;
    }

    @Override
    public boolean markAllAsRead(Long userId) {
        log.info("标记所有通知已读 - 用户ID: {}", userId);
        
        // 查询用户的未读通知数量
        LambdaQueryWrapper<Notification> countWrapper = new LambdaQueryWrapper<>();
        countWrapper.eq(Notification::getUserId, userId)
                   .eq(Notification::getIsRead, false)
                   .eq(Notification::getDeleted, false);
        
        long unreadCount = count(countWrapper);
        if (unreadCount == 0) {
            log.info("用户没有未读通知，不需要标记");
            return true; // 没有未读通知，视为操作成功
        }
        
        log.info("准备标记{}条未读通知为已读", unreadCount);
        
        // 执行更新
        int updatedRows = baseMapper.markAllAsRead(userId);
        boolean success = updatedRows > 0;
        
        log.info("标记所有通知已读 - 结果: {}, 影响行数: {}", success ? "成功" : "失败", updatedRows);
        
        // 再次检查是否还有未读通知
        if (success) {
            long remainingUnread = count(countWrapper);
            log.info("标记操作后，剩余未读通知数量: {}", remainingUnread);
        }
        
        return success;
    }

    @Override
    public boolean deleteNotification(Long notificationId, Long userId) {
        LambdaUpdateWrapper<Notification> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(Notification::getId, notificationId)
               .eq(Notification::getUserId, userId)
               .eq(Notification::getDeleted, false)
               .set(Notification::getDeleted, true);
        return update(wrapper);
    }

    @Override
    public boolean clearAllNotifications(Long userId) {
        LambdaUpdateWrapper<Notification> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(Notification::getUserId, userId)
               .eq(Notification::getDeleted, false)
               .set(Notification::getDeleted, true);
        return update(wrapper);
    }

    @Override
    public Notification createSystemNotification(Long userId, String title, String content, String type) {
        Notification notification = new Notification();
        notification.setUserId(userId);
        notification.setTitle(title);
        notification.setContent(content);
        notification.setType(type);
        notification.setIsRead(false);
        notification.setCreateTime(LocalDateTime.now());
        notification.setDeleted(false);
        save(notification);
        return notification;
    }

    @Override
    public Notification createActionNotification(Long userId, String title, String content, String type,
                                             String actionRoute, String actionText, String actionType) {
        Notification notification = new Notification();
        notification.setUserId(userId);
        notification.setTitle(title);
        notification.setContent(content);
        notification.setType(type);
        notification.setActionRoute(actionRoute);
        notification.setActionText(actionText);
        notification.setActionType(actionType);
        notification.setIsRead(false);
        notification.setCreateTime(LocalDateTime.now());
        notification.setDeleted(false);
        save(notification);
        return notification;
    }
} 